import tkinter as tk
from tkinter import ttk
from tkcalendar import DateEntry
import sqlite3
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.dates import DateFormatter


class HealthTracker:
    def __init__(self, master):
        self.master = master
        master.title("健康参数追踪系统")

        # 初始化数据库
        self.conn = sqlite3.connect('health_data.db')
        self.create_tables()

        # 创建界面组件
        self.create_widgets()
        self.load_settings()

        # 设置初始日期为当天
        self.current_date = datetime.now().strftime('%Y-%m-%d')
        self.date_var.set(self.current_date)

    def create_tables(self):
        cursor = self.conn.cursor()
        cursor.execute('''CREATE TABLE IF NOT EXISTS settings (
                        key TEXT PRIMARY KEY,
                        value REAL)''')
        cursor.execute('''CREATE TABLE IF NOT EXISTS records (
                        date TEXT PRIMARY KEY,
                        weight REAL)''')
        self.conn.commit()

    def create_widgets(self):
        # 健康范围设置区域
        frame_settings = ttk.LabelFrame(self.master, text="健康体重范围设置")
        frame_settings.grid(row=0, column=0, padx=10, pady=10, sticky="ew")

        self.min_weight = tk.DoubleVar()
        self.max_weight = tk.DoubleVar()

        ttk.Label(frame_settings, text="最小体重（kg）:").grid(row=0, column=0)
        ttk.Entry(frame_settings, textvariable=self.min_weight, width=10).grid(row=0, column=1)
        ttk.Label(frame_settings, text="最大体重（kg）:").grid(row=0, column=2)
        ttk.Entry(frame_settings, textvariable=self.max_weight, width=10).grid(row=0, column=3)
        ttk.Button(frame_settings, text="保存范围", command=self.save_range).grid(row=0, column=4, padx=5)

        # 体重录入区域
        frame_entry = ttk.LabelFrame(self.master, text="每日体重录入")
        frame_entry.grid(row=1, column=0, padx=10, pady=10, sticky="ew")

        self.date_var = tk.StringVar()
        self.weight_var = tk.DoubleVar()

        ttk.Label(frame_entry, text="选择日期:").grid(row=0, column=0)
        DateEntry(frame_entry, textvariable=self.date_var, date_pattern='y-mm-dd').grid(row=0, column=1)
        ttk.Label(frame_entry, text="体重（kg）:").grid(row=0, column=2)
        ttk.Entry(frame_entry, textvariable=self.weight_var, width=10).grid(row=0, column=3)
        ttk.Button(frame_entry, text="录入体重", command=self.save_weight).grid(row=0, column=4, padx=5)

        # 图表展示区域
        frame_chart = ttk.LabelFrame(self.master, text="体重变化分析")
        frame_chart.grid(row=2, column=0, padx=10, pady=10, sticky="nsew")

        self.period_var = tk.StringVar(value="周")
        periods = ["周", "月", "季度", "年", "自定义"]

        ttk.Label(frame_chart, text="时间范围:").grid(row=0, column=0)
        ttk.Combobox(frame_chart, textvariable=self.period_var, values=periods).grid(row=0, column=1)
        self.custom_start = DateEntry(frame_chart, date_pattern='y-mm-dd')
        self.custom_end = DateEntry(frame_chart, date_pattern='y-mm-dd')
        ttk.Button(frame_chart, text="生成图表", command=self.plot_data).grid(row=0, column=5, padx=5)

        self.figure = plt.figure(figsize=(8, 4))
        self.canvas = FigureCanvasTkAgg(self.figure, master=frame_chart)
        self.canvas.get_tk_widget().grid(row=1, column=0, columnspan=6, pady=5)

    def save_range(self):
        cursor = self.conn.cursor()
        cursor.execute("INSERT OR REPLACE INTO settings VALUES (?, ?)", ('min', self.min_weight.get()))
        cursor.execute("INSERT OR REPLACE INTO settings VALUES (?, ?)", ('max', self.max_weight.get()))
        self.conn.commit()

    def load_settings(self):
        cursor = self.conn.cursor()
        cursor.execute("SELECT value FROM settings WHERE key='min'")
        if result := cursor.fetchone():
            self.min_weight.set(result[0])
        cursor.execute("SELECT value FROM settings WHERE key='max'")
        if result := cursor.fetchone():
            self.max_weight.set(result[0])

    def save_weight(self):
        cursor = self.conn.cursor()
        cursor.execute("INSERT OR REPLACE INTO records VALUES (?, ?)",
                       (self.date_var.get(), self.weight_var.get()))
        self.conn.commit()
        self.weight_var.set(0.0)

    def get_date_range(self):
        period = self.period_var.get()
        end_date = datetime.now()

        if period == "周":
            start_date = end_date - timedelta(days=7)
        elif period == "月":
            start_date = end_date - timedelta(days=30)
        elif period == "季度":
            start_date = end_date - timedelta(days=90)
        elif period == "年":
            start_date = end_date - timedelta(days=365)
        else:  # 自定义
            start_date = datetime.strptime(self.custom_start.get(), '%Y-%m-%d')
            end_date = datetime.strptime(self.custom_end.get(), '%Y-%m-%d')

        return start_date.strftime('%Y-%m-%d'), end_date.strftime('%Y-%m-%d')

    def plot_data(self):
        start_date, end_date = self.get_date_range()
        cursor = self.conn.cursor()
        cursor.execute("SELECT date, weight FROM records WHERE date BETWEEN ? AND ? ORDER BY date",
                       (start_date, end_date))
        data = cursor.fetchall()

        self.figure.clf()
        ax = self.figure.add_subplot(111)

        if data:
            dates = [datetime.strptime(d[0], '%Y-%m-%d') for d in data]
            weights = [d[1] for d in data]

            ax.plot(dates, weights, 'o-', label='实际体重')
            ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))
            self.figure.autofmt_xdate()

            # 添加健康范围线
            if self.min_weight.get() > 0 and self.max_weight.get() > 0:
                ax.axhline(self.min_weight.get(), color='g', linestyle='--', label='健康下限')
                ax.axhline(self.max_weight.get(), color='r', linestyle='--', label='健康上限')

            ax.set_title(f"体重变化曲线 ({start_date} 至 {end_date})")
            ax.set_xlabel("日期")
            ax.set_ylabel("体重 (kg)")
            ax.grid(True)
            ax.legend()

        self.canvas.draw()


if __name__ == "__main__":
    root = tk.Tk()
    app = HealthTracker(root)
    root.mainloop()


    # pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
    # pip install tkcalendar matplotlib  -i https://pypi.tuna.tsinghua.edu.cn/simple